package com.thedeveloperworldisyours.fullrecycleview.indexed;

import com.ohos.BaseItemWithIndexerProvider;
import com.thedeveloperworldisyours.fullrecycleview.ResourceTable;
import com.thedeveloperworldisyours.fullrecycleview.sections.model.ElementList;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.app.Context;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

/**
 * Created by javierg on 18/07/2017.
 */

public class IndexedAdapter extends BaseItemWithIndexerProvider {

    public static final int ITEM = 1;

    public static final int SECTION = 2;

    private HashMap<String, Integer> mMapIndex;
    private List<String> mSections;
    private List<ElementList> mList;
    private LayoutScatter scatter;

    @Override
    public List<String> getSections() {
        return mSections;
    }

    public void setmSections(List<String> mSections) {
        this.mSections = mSections;
    }

    @Override
    public int getPositionForSection(int position) {
        return mMapIndex.get(mSections.get(position));
    }

    @Override
    public int getSectionForPosition(int i) {
        return 0;
    }

    static class SectionHolder {
        Text mTextViewSection;

        SectionHolder(Component itemView) {
            mTextViewSection = (Text) itemView.findComponentById(ResourceTable.Id_indexed_item_list_view_header_title);
        }
    }

    static class DataObjectHolder {
        Text mName;

        DataObjectHolder(Component itemView) {
            mName = (Text) itemView.findComponentById(ResourceTable.Id_indexed_item_list_view_name);
        }
    }

    public IndexedAdapter(LayoutScatter scatter, List<ElementList> list, List<String> sections, HashMap<String, Integer> mapIndex) {
        this.scatter = scatter;
        mList = list;
        mSections = sections;
        mMapIndex = mapIndex;
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
        if (component == null) {
            int componentType = getItemComponentType(position);
            if (componentType == ITEM) {
                component = scatter.parse(ResourceTable.Layout_indexed_item_list_view, componentContainer, false);
                DataObjectHolder dataObjectHolder = new DataObjectHolder(component);
                dataObjectHolder.mName.setText(mList.get(position).getName());
                component.setTag(dataObjectHolder);
            } else {
                component = scatter.parse(ResourceTable.Layout_indexed_item_list_view_header, componentContainer, false);
                SectionHolder sectionHolder = new SectionHolder(component);
                component.setTag(sectionHolder);
                sectionHolder.mTextViewSection.setText(mList.get(position).getName());
            }
        } else {
            if (component.getTag() instanceof DataObjectHolder) {
                ((DataObjectHolder) component.getTag()).mName.setText(mList.get(position).getName());
            } else {
                if (component.getTag() instanceof SectionHolder) {
                    ((SectionHolder) component.getTag()).mTextViewSection.setText(mList.get(position).getName());
                }
            }
        }
        setAnimation(component, position);
        return component;
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int id) {
        return id;
    }

    @Override
    public int getCount() {
        return mList == null ? 0 : mList.size();
    }

    public void refreshData(List<ElementList> dataset) {
        mList.clear();
        mList.addAll(dataset);
        notifyDataChanged();
    }

    @Override
    public int getItemComponentType(int position) {
        if (mList.get(position).isSection()) {
            return SECTION;
        } else {
            return ITEM;
        }
    }

    private HashSet<Integer> positionSet = new HashSet<>();

    /**
     * Here is the key method to apply the animation
     *
     * @param viewToAnimate 需要动画的控件
     * @param position      位置
     */
    private void setAnimation(Component viewToAnimate, int position) {

        viewToAnimate.setBindStateChangedListener(new Component.BindStateChangedListener() {
            private AnimatorValue animatorValue;

            @Override
            public void onComponentBoundToWindow(Component component) {
                if (positionSet.contains(position)) {
                    component.setAlpha(1f);
                    component.setTranslationX(0);
                    return;
                }
                animatorValue = new AnimatorValue();
                animatorValue.setDuration(400);
                animatorValue.setValueUpdateListener((animatorValue, v) -> {
                    component.setAlpha(v);
                    component.setTranslationX(-component.getWidth() / 2.0f + (v * component.getWidth() / 2.0f));
                });
                animatorValue.start();
                positionSet.add(position);
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {
                if (animatorValue != null) {
                    animatorValue.cancel();
                    animatorValue.release();
                }
                component.setAlpha(0);
                component.setTranslationX(-component.getWidth() / 2.0f);
            }
        });
    }
}
